<template>
  <div id='xterm'></div>
</template>

<script setup lang="ts">
import { onMounted, onBeforeUnmount, ref } from 'vue'
import 'xterm/css/xterm.css'
import { Terminal } from 'xterm';
import { FitAddon } from "xterm-addon-fit";
import { AttachAddon } from 'xterm-addon-attach'

const wsInstance = ref<WebSocket>()
const xtermInstance = ref<Terminal>()

onMounted(() => {
  setTimeout(() => {
    initTerm()
  }, 200);
})

onBeforeUnmount(() => {
  wsInstance.value?.close()
  xtermInstance.value?.dispose()
})

//初始化当前系统环境，返回终端的 pid，标识当前终端的唯一性
const initSysEnv = async () =>
await fetch("http://127.0.0.1:8003/terminal", {
  method: 'post'
})
  .then((res) => res.json())
  .then((res) => res)
  .catch((err) => {
    throw new Error(err);
  });

const initSocket = (pid: string) => {
  const ws = new WebSocket('ws://localhost:8003/socket/' + pid)
  wsInstance.value = ws
  return ws
}

const initTerm = async () => {
  const element = document.getElementById('xterm')
  if (!element) return
  // 设置了cols或者fitAddon.fit(); 当一行字符超过80个过会替换现在的内容，否则换行
  const term = new Terminal({
    cursorBlink: true, // 关闭闪烁
    cursorStyle: 'underline', // 光标样式
    scrollback: 100, //当行的滚动超过初始值时保留行视窗，越大回滚能看到的内容越多
    fontFamily: 'Menlo, Monaco, "Courier New", monospace',
    fontWeight: 400,
    fontSize: 13,
    rows: 50,
    cols: 130
  })
  xtermInstance.value = term
  const pid = await initSysEnv()
  const socket = initSocket(pid)
  const fitAddon = new FitAddon()
  fitAddon.fit()
  term.loadAddon(fitAddon)
  const attachAddon = new AttachAddon(socket)
  term.loadAddon(attachAddon)
  term.open(element)
}

</script>

<style scoped lang="scss">
#xterm {
width: 100%;
height: 100%;
}
</style>
